#region OpenNETCF Copyright Information
/*
Copyright (c) 2007 OpenNETCF Consulting, LLC

Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
and associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial 
portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE 
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#endregion

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using OpenNETCF.WindowsMobile.Ink;
using Microsoft.WindowsMobile.PocketOutlook;
using System.IO;

namespace InkNotesCF
{
    public partial class Form1 : Form
    {
        // Modes
        private const int INKING_MODE = 1;
        private const int HIGHLIGHTER_MODE = 2;
        private const int ERASER_MODE = 3;
        private const int SELECTION_MODE = 4;

        // Pen width
        private const float PENWIDTHFINE = 1.0f;
        private const float PENWIDTHMEDIUM = 53.0f;
        private const float PENWIDTHTHICK = 100.0f;
        private const float PENWIDTHMARKER = 200.0f;

        //Highlighter PenStyle
        private PENSTYLE m_psHighlighter;
        private PENSTYLE m_psPen;

        //Temp attachment file for email
        private string m_AttachmentTempFile = null;

        //Note object to load and save
        private NoteBase m_note;

        public Form1()
        {
            InitializeComponent();

            //Initialize pens
            InitializePens();

            //Set a blank canvas
            New(false);

            //Enable the buttons
            EnablePushButton(btnPen);
        }

        private void InitializePens()
        {
            //Set the normal pen
            m_psPen.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(m_psPen);
            m_psPen.crColor = ToRGB(Color.Blue);
            m_psPen.dPenWidth = PENWIDTHMEDIUM;
            m_psPen.ptPenType = IC_PENTYPE.NORMAL;

            //Set the highlighter pen
            m_psHighlighter.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(m_psHighlighter);
            m_psHighlighter.crColor = ToRGB(Color.Yellow);
            m_psHighlighter.dPenWidth = PENWIDTHMARKER;
            m_psHighlighter.ptPenType = IC_PENTYPE.HIGHLIGHTER;
        }

        private void CreateNewCanvas()
        {
            if(inkCanvas1 != null)
                this.inkCanvas1.CreateControl();
            
            //this.inkCanvas1 = new InkCanvas();
            this.inkCanvas1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            //this.inkCanvas1.Dock = System.Windows.Forms.DockStyle.Fill;
            //this.inkCanvas1.Location = new System.Drawing.Point(0, 0);
            //this.inkCanvas1.Name = "inkCanvas1";
            //this.inkCanvas1.Size = new System.Drawing.Size(240, 268);
            //this.inkCanvas1.TabIndex = 1;
            //this.inkCanvas1.StrokeAdded += new System.EventHandler<OpenNETCF.WindowsMobile.Ink.StrokeEventArgs>(this.StrokeAddedDeleted);
            //this.inkCanvas1.StrokeDeleted += new System.EventHandler<OpenNETCF.WindowsMobile.Ink.StrokeEventArgs>(this.StrokeAddedDeleted);

            //Set the normal pen
            inkCanvas1.SetPenStyle(m_psPen);

            //Set the canvas to autoscroll
            inkCanvas1.SetAutoScroll(true);

            //Set the Zoom level to 100
            inkCanvas1.ZoomLevel = 100;


        }

        private int ToRGB(Color color)
        {
            return (color.B << 16) | (color.G << 8) | color.R;
        }

        private void toolBar1_ButtonClick(object sender, ToolBarButtonClickEventArgs e)
        {
            //Enable the push buttons
            EnablePushButton(e.Button);

            switch (e.Button.Tag.ToString())
            {
                case "Erase":
                    inkCanvas1.Mode = IC_EDITINGMODE.DELETE;
                    break;
                case "Laso":
                    inkCanvas1.Mode = IC_EDITINGMODE.SELECT;
                    break;
                case "Highlight":
                    inkCanvas1.Mode = IC_EDITINGMODE.INK;
                    inkCanvas1.PenStyle = m_psHighlighter;
                    break;
                case "Pen":
                    inkCanvas1.Mode = IC_EDITINGMODE.INK;
                    inkCanvas1.PenStyle = m_psPen;
                    break;
                case "ZoomIn":
                    ZoomIn();
                    break;
                case "ZoomOut":
                    ZoomOut();
                    break;
            }
        }

        private void ZoomIn()
        {
            int currentZoom = inkCanvas1.ZoomLevel;
            int newZoom = 0;
            newZoom = currentZoom + 20;
            inkCanvas1.ZoomLevel = newZoom;
            UpdateZoomButtons();
        }

        private void ZoomOut()
        {
            int currentZoom = inkCanvas1.ZoomLevel;
            int newZoom = 0;
            newZoom = currentZoom - 20;
            inkCanvas1.ZoomLevel = newZoom;
            UpdateZoomButtons();
        }

        private void UpdateZoomButtons()
        {
            int currentZoom = inkCanvas1.ZoomLevel;
            // Disable the zoom in button if we're at max zooming level else enable it
            //
            if (currentZoom >= 415) //Changed from 500 to 415 as 415 seems to be the max level
            {
                this.btnZoomIn.Enabled = false;
            }
            else
            {
                this.btnZoomIn.Enabled = true;
            }

            //
            // Disable the zoom in button if we're at min zooming level else enable it
            //
            if (currentZoom <= 38) //Changed from 20 to 38 as 38 is the min level
            {
                this.btnZoomOut.Enabled = false;
            }
            else
            {
                this.btnZoomOut.Enabled = true;
            }
        }

        private void UpdateUndoRedoButtons()
        {
            miRedo.Enabled = inkCanvas1.CanRedo();
            miUndo.Enabled = inkCanvas1.CanUndo();
        }

        private void MenuHandler(object sender, EventArgs e)
        {
            switch(((MenuItem)sender).Text)
            {
                case "Open":
                    Open();
                    break;
                case "New":
                    New(true);
                    break;
                case "Save":
                    Save();
                    break;
                case "Email":
                    Email();
                    break;
                case "Exit":
                    this.Close();
                    break;
                case "Cut":
                    inkCanvas1.Cut();
                    break;
                case "Copy":
                    inkCanvas1.Copy();
                    break;
                case "Paste":
                    inkCanvas1.Paste();
                    break;
                case "Undo":
                    Undo();
                    break;
                case "Redo":
                    Redo();
                    break;
                case "Back Color":
                    SetBackColor();
                    break;
            }

        }

        private void SetBackColor()
        {
            using (OpenNETCF.Windows.Forms.ColorDialog dlg = new OpenNETCF.Windows.Forms.ColorDialog())
            {
                dlg.AllowFullOpen = true;
                dlg.Color = Color.FromArgb(inkCanvas1.GetPenStyle().crColor);
                if (dlg.ShowDialog() == DialogResult.OK)
                    inkCanvas1.SetCanvasColor(dlg.Color);
            }
        }

        private void Redo()
        {
            inkCanvas1.Redo();
            UpdateUndoRedoButtons();
        }

        private void Undo()
        {
            inkCanvas1.Undo();
            UpdateUndoRedoButtons();
        }

        private void Email()
        {
            OutlookSession session = new OutlookSession();
            if (session.EmailAccounts.Count > 0)
            {
                //Default to the first one
                EmailAccount acct = new OutlookSession().EmailAccounts[0];
                EmailMessage msg = new EmailMessage();
                object data = inkCanvas1.GetInkData(IC_INKENCODING.GIF);
                FileStream fs = new FileStream(AttachmentTempFile, FileMode.Create, FileAccess.ReadWrite, FileShare.None, ((byte[])data).Length);
                fs.Write(((byte[])data), 0, ((byte[])data).Length);
                fs.Close();
                Attachment note = new Attachment(AttachmentTempFile);
                msg.Attachments.Add(note);
                msg.Send(acct);
                msg.Subject = "Test attachement";
                msg.BodyText = "Sample from InkNoteCF";
            }
            session.Dispose();
        }

        private void Save()
        {
            //Save the inkdata to the note
            m_note.InkData = inkCanvas1.GetInkData(IC_INKENCODING.BASE64).ToString();

            //If it is new then ask for a filename
            if (m_note.IsNew)
            {
                using (SaveFileDialogHelper dlg = new SaveFileDialogHelper("Ink notes (*.ink)|*.ink"))
                {
                    if (dlg.ShowDialog() == DialogResult.OK)
                    {
                        //Set the title, object/page Guids
                        m_note.Title = dlg.Filename;
                        m_note.ObjectGuid = Guid.NewGuid().ToString();
                        m_note.PageGuid = Guid.NewGuid().ToString();

                        //Save the note
                        m_note.SaveToFile(dlg.Filename);
                    }
                }
            }
            else
            {
                //save the note to the existing filename as it was opened from the file system
                m_note.Save();
            }
        }

        private void New(bool clearCanvas)
        {
            if (UseOneNote2007)
                m_note = new Note2007();
            else
                m_note = new Note();

            if (clearCanvas)
            {
                //inkCanvas1.ClearCanvas(); //Calling this seems to not save the base64 data properly and adds an /0 to the string
                CreateNewCanvas();
            }

            inkCanvas1.SetCanvasColor(Color.LightYellow);
            inkCanvas1.ZoomLevel = 100;
            UpdateUndoRedoButtons();
            UpdateZoomButtons();
        }

        private void Open()
        {
            using (OpenFileDialogHelper dlg = new OpenFileDialogHelper("Ink notes (*.ink)|*.ink"))
            {
                if (dlg.ShowDialog() == DialogResult.OK)
                {
                    try
                    {
                        New(true);
                        m_note.LoadFromFile(dlg.Filename);
                        inkCanvas1.LoadInkData(m_note.InkData);
                    }
                    catch (Exception e)
                    {
                        MessageBox.Show(string.Format("Unable to open ink file. (Error:{0})", e.Message));
                        New(true);
                    }
                    
                }
            }
        }

        private void PenMenuHandler(object sender, EventArgs e)
        {
            switch (((MenuItem)sender).Text)
            {
                //Pen Width
                case "Fine":
                    SetPenWidth(PENWIDTHFINE);
                    miPenFine.Checked = true;
                    miPenMedium.Checked = false;
                    miPenThick.Checked = false;
                    miPenMarker.Checked = false;
                    break;
                case "Medium":
                    SetPenWidth(PENWIDTHMEDIUM);
                    miPenFine.Checked = false;
                    miPenMedium.Checked = true;
                    miPenThick.Checked = false;
                    miPenMarker.Checked = false;
                    break;
                case "Thick":
                    SetPenWidth(PENWIDTHTHICK);
                    miPenFine.Checked = false;
                    miPenMedium.Checked = false;
                    miPenThick.Checked = true;
                    miPenMarker.Checked = false;
                    break;
                case "Marker":
                    SetPenWidth(PENWIDTHMARKER);
                    miPenFine.Checked = false;
                    miPenMedium.Checked = false;
                    miPenThick.Checked = false;
                    miPenMarker.Checked = true;
                    break;
                //Colours
                case "Blue":
                    SetPenColor(Color.Blue);
                    miPenBlack.Checked = true;
                    miPenRed.Checked = false;
                    miPenGreen.Checked = false;
                    miPenYellow.Checked = false;
                    miPenBlack.Checked = false;
                    miPenCustom.Checked = false;
                    break;
                case "Red":
                    SetPenColor(Color.Red);
                    miPenBlack.Checked = false;
                    miPenRed.Checked = true;
                    miPenGreen.Checked = false;
                    miPenYellow.Checked = false;
                    miPenBlack.Checked = false;
                    miPenCustom.Checked = false;
                    break;
                case "Green":
                    SetPenColor(Color.Green);
                    miPenBlack.Checked = false;
                    miPenRed.Checked = false;
                    miPenGreen.Checked = true;
                    miPenYellow.Checked = false;
                    miPenBlack.Checked = false;
                    miPenCustom.Checked = false;
                    break;
                case "Yellow":
                    SetPenColor(Color.Yellow);
                    miPenBlack.Checked = false;
                    miPenRed.Checked = false;
                    miPenGreen.Checked = false;
                    miPenYellow.Checked = true;
                    miPenBlack.Checked = false;
                    miPenCustom.Checked = false;
                    break;
                case "Black":
                    SetPenColor(Color.Black);
                    miPenBlack.Checked = false;
                    miPenRed.Checked = false;
                    miPenGreen.Checked = false;
                    miPenYellow.Checked = false;
                    miPenBlack.Checked = true;
                    miPenCustom.Checked = false;
                    break;
                case "Custom":
                    using (OpenNETCF.Windows.Forms.ColorDialog dlg = new OpenNETCF.Windows.Forms.ColorDialog())
                    {
                        dlg.AllowFullOpen = true;
                        dlg.Color = Color.FromArgb(inkCanvas1.GetPenStyle().crColor);
                        if (dlg.ShowDialog() == DialogResult.OK)
                        {
                            SetPenColor(dlg.Color);
                            miPenBlack.Checked = false;
                            miPenRed.Checked = false;
                            miPenGreen.Checked = false;
                            miPenYellow.Checked = false;
                            miPenBlack.Checked = false;
                            miPenCustom.Checked = true;
                        }
                    }
                    break;
            }

            //Set the pen
            inkCanvas1.PenStyle = m_psPen;

            //Set the buttons
            EnablePushButton(btnPen);
        }

        private void SetPenWidth(float penwidth)
        {
            m_psPen.dPenWidth = penwidth;
        }

        private void SetPenColor(Color color)
        {
            m_psPen.crColor = ToRGB(color); //Convert to RGB
        }
      
        private void HighLightMenuHandler(object sender, EventArgs e)
        {
            switch (((MenuItem)sender).Text)
            {
                case "Green":
                    m_psHighlighter.crColor = ToRGB(Color.Green);
                    miHighlightGreen.Checked = true;
                    miHighlightYellow.Checked = false;
                    break;
                case "Yellow":
                    m_psHighlighter.crColor = ToRGB(Color.Yellow);
                    miHighlightGreen.Checked = false;
                    miHighlightYellow.Checked = true;
                    break;
            }

            //Set the pen
            inkCanvas1.PenStyle = m_psHighlighter;

            //Set the buttons
            EnablePushButton(btnHiLight);
        }

        private void EnableHighlightCheck()
        {
        }

        private void SetHighlightWidth(float penwidth)
        {
            m_psHighlighter.dPenWidth = penwidth;
        }

        private void SetHighlightColor(Color color)
        {
            m_psHighlighter.crColor = ToRGB(color); //Convert to RGB
        }

        private void EnablePushButton(ToolBarButton btn)
        {
            if (btn == btnPen)
            {
                btnPen.Pushed = true;
                btnHiLight.Pushed = false;
                btnLaso.Pushed = false;
                btnErase.Pushed = false;
            }
            else if (btn == btnHiLight)
            {
                btnPen.Pushed = false;
                btnHiLight.Pushed = true;
                btnLaso.Pushed = false;
                btnErase.Pushed = false;
            }
            else if (btn == btnErase)
            {
                btnPen.Pushed = false;
                btnHiLight.Pushed = false;
                btnLaso.Pushed = false;
                btnErase.Pushed = true;
            }
            else if (btn == btnLaso)
            {
                btnPen.Pushed = false;
                btnHiLight.Pushed = false;
                btnLaso.Pushed = true;
                btnErase.Pushed = false;
            }
        }

        private void StrokeAddedDeleted(object sender, StrokeEventArgs e)
        {
            UpdateUndoRedoButtons();
        }

        private string AttachmentTempFile
        {
            get
            {
                if (m_AttachmentTempFile == null)
                {
                    m_AttachmentTempFile = Path.Combine(
                        Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase),
                        "noteImage.gif");
                }
                return m_AttachmentTempFile;
            }
        }

        private void OneNoteFormat(object sender, EventArgs e)
        {
            if (sender == miOneNote2003)
            {
                miOneNote2003.Checked = true;
                miOneNote2007.Checked = false;
            }
            else if (sender == miOneNote2007)
            {
                miOneNote2003.Checked = false;
                miOneNote2007.Checked = true;
            }
        }

        private bool UseOneNote2007
        {
            get
            {
                return miOneNote2007.Checked;
            }
        }
     
    }
}